using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using ArticleManagementSystem.Api.Entity;
using ArticleManagementSystem.Api.Db;
using System;
using Microsoft.EntityFrameworkCore;

namespace ArticleManagementSystem.Api.Repostisory
{
    public class EfRepostisory<T> : IRepostisory<T> where T : BaseInit
    {

        private DataBase _db;

        public EfRepostisory(DataBase db)
        {
            _db = db;
        }

        private DbSet<T> _entity;

        protected DbSet<T> Entity
        {
            get
            {
                if (_entity == null)
                {
                    _entity = _db.Set<T>();
                }
                return _entity;
            }
        }
        public IQueryable<T> Table
        {
            get
            {
                return Entity.AsQueryable<T>();
            }
        }
        public void Deleted(object Id)
        {
            var t = Entity.Find(Id);
            if (t == null)
            {
                throw new ArgumentNullException(nameof(t));
            }
            _db.Remove(t);
            _db.SaveChanges();
        }

        public void DeletedBulk(IEnumerable<object> Ids)
        {
            var ii = new List<int>();
            foreach (var item in Ids)
            {
                var tmp = (int)item;
                ii.Add(tmp);
            }
            var ts = Entity.Where(x => ii.Contains(x.Id)).ToList();
            _db.RemoveRange(ts);
            _db.SaveChanges();
        }

        public T GetById(object Id)
        {
            return Entity.Find(Id);
        }

        public async Task InserAsync(T entity)
        {
            if (entity == null)
            {
                throw new ArgumentNullException();
            }

            entity.IsActived = true;
            entity.IsDeleted = false;
            entity.CreatedTime = DateTime.Now;
            entity.UpdatedTime = DateTime.Now;
            // entity.DisplayOrder = 0;

            await Entity.AddAsync(entity);
            await _db.SaveChangesAsync();
        }

        public async Task InserAsyncBulk(IEnumerable<T> entitys)
        {
            foreach (var entity in entitys)
            {
                entity.IsActived = true;
                entity.IsDeleted = false;
                entity.CreatedTime = DateTime.Now;
                entity.UpdatedTime = DateTime.Now;
                // entity.DisplayOrder = 0;
            }
            await Entity.AddRangeAsync(entitys);
            await _db.SaveChangesAsync();
        }

        public void Insert(T entity)
        {
            if (entity == null)
            {
                throw new ArgumentNullException();
            }

            entity.IsActived = true;
            entity.IsDeleted = false;
            entity.CreatedTime = DateTime.Now;
            entity.UpdatedTime = DateTime.Now;

            Entity.Add(entity);
            _db.SaveChanges();
        }

        public void InsertBulk(IEnumerable<T> entitys)
        {
            foreach (var entity in entitys)
            {
                entity.IsActived = true;
                entity.IsDeleted = false;
                entity.CreatedTime = DateTime.Now;
                entity.UpdatedTime = DateTime.Now;
                // entity.DisplayOrder = 0;
            }
            Entity.AddRange(entitys);
            _db.SaveChanges();
        }

        public void Updated(T entity)
        {
            if (entity == null)
            {
                throw new ArgumentNullException(nameof(entity));
            }

            entity.UpdatedTime = DateTime.Now;
            Entity.Update(entity);
            _db.SaveChanges();
        }

        public void UpdatedBulk(IEnumerable<T> entitys)
        {
            foreach (var entity in entitys)
            {
                entity.UpdatedTime = DateTime.Now;
            }

            Entity.UpdateRange(entitys);
            _db.SaveChanges();
        }
    }
}